package similarity;

import java.util.ArrayList;

import type.Movie;
import type.Rating;
import type.Sex;
import type.User;
import database.MovieLensDatabase;

public class PearsonCorrelation {
		
	static public double betweenUser(User u, User v)
	{
		double ruAverage = u.getMeanRating();
		double rvAverage = v.getMeanRating();
		ArrayList<Movie> itemIntersection = GetItemIntersection(u,v);
		
		if (itemIntersection.size() == 0)
			return 0.0;
		
		double sum1 = 0.0;
		double sum2 = 0.0;
		double sum3 = 0.0;
		
		for (Movie movie : itemIntersection) {
			double rui = u.getRatingList().get(movie).getRating();
			double rvi = v.getRatingList().get(movie).getRating();
			sum1 += (rui - ruAverage) * (rvi - rvAverage);
			sum2 += Math.pow(rui - ruAverage, 2.0);
			sum3 += Math.pow(rvi - rvAverage, 2.0);
		}
		sum2 += 1E-10;
		sum3 += 1E-10;
		
		double similitude = sum1 / Math.sqrt(sum2 * sum3);

		return (itemIntersection.size()/(itemIntersection.size() + 30.0)) * similitude;
	}
	

	
	static public double betweenItem(Movie i, Movie j)
	{
		double riAverage = i.getMeanRating();
		double rjAverage = j.getMeanRating();
		ArrayList<User> userIntersection = GetUserIntersection(i,j);
		
		if (userIntersection.size() == 0)
			return 0.0;
		
		double sum1 = 0.0;
		double sum2 = 0.0;
		double sum3 = 0.0;
		
		for (User user : userIntersection) {
			double rui = i.getRatingList().get(user).getRating();
			double ruj = j.getRatingList().get(user).getRating();
			sum1 += (rui - riAverage) * (ruj - rjAverage);
			sum2 += Math.pow(rui - riAverage, 2.0);
			sum3 += Math.pow(ruj - rjAverage, 2.0);
		}
		sum2 += 1E-10;
		sum3 += 1E-10;
		double similitude = sum1 / Math.sqrt(sum2 * sum3); 
		return (userIntersection.size()/(userIntersection.size() + 30.0)) * similitude;
	}
	
	static private ArrayList<Movie> GetItemIntersection(User u, User v){
		ArrayList<Movie> itemIntersection = new ArrayList<>();
		
		for (Movie item : u.getRatingList().keySet()) {
			if (v.getRatingList().keySet().contains(item))
				itemIntersection.add(item);
		}
		
		return itemIntersection;
	}
	
	static private ArrayList<User> GetUserIntersection(Movie i, Movie j){
		ArrayList<User> userIntersection = new ArrayList<>();
		
		for (User user: i.getRatingList().keySet()) {
			if (j.getRatingList().keySet().contains(user))
				userIntersection.add(user);
		}
		
		return userIntersection;
	}
	
	public static void main(String[] args) {
		MovieLensDatabase db = new MovieLensDatabase("..\\..\\database\\ml-100k");
		ArrayList<Rating> testRatings = db.selectRatingSet(0);
		User u1 = testRatings.get(0).getUser();
		User u2 = testRatings.get(1000).getUser();
		User u3 = new User(999, 99, Sex.Male, "rien", "q1w2e3");
		System.out.println(u1.toString());
		System.out.println(u2.toString());
		
		System.out.println( PearsonCorrelation.betweenUser(u1, u1) );
		System.out.println( PearsonCorrelation.betweenUser(u1, u2) );
		System.out.println( PearsonCorrelation.betweenUser(u1, u3) );
	}
}
